package com.cxrj.zhsq.utils;

import java.io.File;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
 * 文件上传
 * @author wangm
 * @created @2018年5月22日-下午2:58:41
 *
 */
@RestController
public class UploadController {
	
	private String PATH_LINE = File.separator;  
	
	private static final ObjectMapper objectMapper = new ObjectMapper();
	
	//	private PrintWriter writer = null;
	/**
	 * 图片上传
	 * folderId是主键id，作为文件储存的文件夹id
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/upload_img", method = RequestMethod.POST)  
    @ResponseBody  
    public void fileUpload(HttpServletRequest request,   
            HttpServletResponse response,  
            @RequestParam("imgFile") MultipartFile[] imgFile) {  
        try {  
            response.setCharacterEncoding("utf-8");  
            String folderId = request.getParameter("folderId");
            if(folderId==null || folderId.equals("")) {
            	folderId = UUID.randomUUID().toString();
            }
            PrintWriter out = response.getWriter();  
            //文件保存本地目录路径  
            String filePath = "upload" + File.separator + "zhsq_xg" + File.separator;
            String savePath = File.separator + request.getSession().getServletContext().getRealPath("/") + ".." + File.separator + filePath;  
            // String savePath = "C:" + PATH_LINE +"upload"+PATH_LINE;  
            //文件保存目录URL  
            String saveUrl = ".." + File.separator + filePath; 
            if(!ServletFileUpload.isMultipartContent(request)){  
                out.print(getError("请选择文件。"));  
                out.close();  
                return;  
            }  
            //检查目录  
            File uploadDir = new File(savePath);  
            if(!uploadDir.isDirectory()){  
                out.print(getError("上传目录不存在。"));  
                out.close();  
                return;  
            }  
            //检查目录写权限  
            if(!uploadDir.canWrite()){  
                out.print(getError("上传目录没有写权限。"));  
                out.close();  
                return;  
            }  
  
            String dirName = request.getParameter("dir");  
            if (dirName == null) {  
                dirName = "image";  
            }  
              
            //定义允许上传的文件扩展名  
            Map<String, String> extMap = new HashMap<String, String>();  
            extMap.put("image", "gif,jpg,jpeg,png,bmp");  
            extMap.put("flash", "swf,flv");  
            extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");  
            extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,xml,txt,zip,rar,gz,bz2");  
              
            if(!extMap.containsKey(dirName)){  
                out.print(getError("目录名不正确。"));  
                out.close();  
                return;  
            }  
            /*savePath += dirName + PATH_LINE;  
            saveUrl += dirName + PATH_LINE;  
            File saveDirFile = new File(savePath);  
            if (!saveDirFile.exists()) {  
                saveDirFile.mkdirs();  
            }  */
            //创建文件夹  
            savePath += folderId + PATH_LINE;  
            saveUrl += folderId + PATH_LINE;  
            File dirFile = new File(savePath);  
            if (!dirFile.exists()) {  
                dirFile.mkdirs();  
            }
              
            //最大文件大小  
            long maxSize = 1000000;  
              
            // 保存文件  
            for(MultipartFile iFile : imgFile){  
                String fileName = iFile.getOriginalFilename();  
                  
                //检查文件大小  
                if(iFile.getSize() > maxSize){  
                    out.print(getError("上传文件大小超过限制。"));  
                    out.close();  
                    return;  
                }  
                //检查扩展名  
                String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();  
                if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){  
                    //return getError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。");  
                    out.print(getError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。"));  
                    out.close();  
                    return;  
                }  
  
                String newFileName = UUID.randomUUID().toString() + "." + fileExt;  
                try{  
                    File uploadedFile = new File(savePath, newFileName);  
                    // 写入文件  
                    FileUtils.copyInputStreamToFile(iFile.getInputStream(), uploadedFile);  
                }catch(Exception e){  
                    out.print(getError("上传文件失败。"));  
                    out.close();  
                    return;  
                }  
                  
                JSONObject obj = new JSONObject();    
                obj.put("error", 0);    
                obj.put("url", saveUrl + newFileName);   
                obj.put("fileName", folderId+"/"+newFileName);  
                  
                out.print(obj.toJSONString());  
                out.close();  
            }  
        } catch (Exception e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
	
	/**
	 * 图片上传
	 * folderId是主键id，作为文件储存的文件夹id
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/upload_img1", method = RequestMethod.POST)  
    @ResponseBody  
    public void fileUpload1(HttpServletRequest request,   
            HttpServletResponse response,  
            @RequestParam("imgFile1") MultipartFile[] imgFile1) {  
        try {  
            response.setCharacterEncoding("utf-8");  
            String folderId = request.getParameter("folderId");
            if(folderId==null || folderId.equals("")) {
            	folderId = UUID.randomUUID().toString();
            }
            PrintWriter out = response.getWriter();  
            //文件保存本地目录路径  
            String filePath = "upload" + File.separator + "zhsq_xg" + File.separator;
            String savePath = File.separator + request.getSession().getServletContext().getRealPath("/") + ".." + File.separator + filePath;  
            // String savePath = "C:" + PATH_LINE +"upload"+PATH_LINE;  
            //文件保存目录URL  
            String saveUrl = ".." + File.separator + filePath; 
            if(!ServletFileUpload.isMultipartContent(request)){  
                out.print(getError("请选择文件。"));  
                out.close();  
                return;  
            }  
            //检查目录  
            File uploadDir = new File(savePath);  
            if(!uploadDir.isDirectory()){  
                out.print(getError("上传目录不存在。"));  
                out.close();  
                return;  
            }  
            //检查目录写权限  
            if(!uploadDir.canWrite()){  
                out.print(getError("上传目录没有写权限。"));  
                out.close();  
                return;  
            }  
  
            String dirName = request.getParameter("dir");  
            if (dirName == null) {  
                dirName = "image";  
            }  
              
            //定义允许上传的文件扩展名  
            Map<String, String> extMap = new HashMap<String, String>();  
            extMap.put("image", "gif,jpg,jpeg,png,bmp");  
            extMap.put("flash", "swf,flv");  
            extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");  
            extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,xml,txt,zip,rar,gz,bz2");  
              
            if(!extMap.containsKey(dirName)){  
                out.print(getError("目录名不正确。"));  
                out.close();  
                return;  
            }  
            /*savePath += dirName + PATH_LINE;  
            saveUrl += dirName + PATH_LINE;  
            File saveDirFile = new File(savePath);  
            if (!saveDirFile.exists()) {  
                saveDirFile.mkdirs();  
            }  */
            //创建文件夹  
            savePath += folderId + PATH_LINE;  
            saveUrl += folderId + PATH_LINE;  
            File dirFile = new File(savePath);  
            if (!dirFile.exists()) {  
                dirFile.mkdirs();  
            }
              
            //最大文件大小  
            long maxSize = 1000000;  
              
            // 保存文件  
            for(MultipartFile iFile : imgFile1){  
                String fileName = iFile.getOriginalFilename();  
                  
                //检查文件大小  
                if(iFile.getSize() > maxSize){  
                    out.print(getError("上传文件大小超过限制。"));  
                    out.close();  
                    return;  
                }  
                //检查扩展名  
                String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();  
                if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){  
                    //return getError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。");  
                    out.print(getError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。"));  
                    out.close();  
                    return;  
                }  
  
                String newFileName = UUID.randomUUID().toString() + "." + fileExt;  
                try{  
                    File uploadedFile = new File(savePath, newFileName);  
                    // 写入文件  
                    FileUtils.copyInputStreamToFile(iFile.getInputStream(), uploadedFile);  
                }catch(Exception e){  
                    out.print(getError("上传文件失败。"));  
                    out.close();  
                    return;  
                }  
                  
                JSONObject obj = new JSONObject();    
                obj.put("error", 0);    
                obj.put("url", saveUrl + newFileName);   
                obj.put("fileName", folderId+"/"+newFileName);  
                  
                out.print(obj.toJSONString());  
                out.close();  
            }  
        } catch (Exception e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
	
	/**
	 * 删除文件夹及文件夹下的所有文件
	 * folderName为文件夹id，一般是主键id
	 * @param folderName
	 * @param request
	 * @param response
	 * @return
	 */
	@SuppressWarnings("unused")
	public static boolean deleteDir(String folderName,HttpServletRequest request,HttpServletResponse response) {
		 String filePath = "upload" + File.separator + "zhsq_xg" + File.separator + folderName;
         String savePath = File.separator + request.getSession().getServletContext().getRealPath("/") + ".." + File.separator + filePath;  
         // String savePath = "C:" + PATH_LINE +"upload"+PATH_LINE;  
         //文件保存目录URL  
         String saveUrl = ".." + File.separator + filePath; 
         File dir = new File(savePath);
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir((folderName + File.separator + children[i]), request, response);
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }
	
	private Map<String, Object> getError(String errorMsg) {  
        Map<String, Object> errorMap = new HashMap<String, Object>();  
        errorMap.put("error", 1);  
        errorMap.put("message", errorMsg);  
        return errorMap;  
    }  
	
	@SuppressWarnings("unchecked")
	@RequestMapping(value="/mien_file_manager")
    public void file_manager(HttpServletRequest request, HttpServletResponse response) throws Exception{
         
        ServletContext application = request.getSession().getServletContext();
        ServletOutputStream out = response.getOutputStream();
        // 根目录路径，可以指定绝对路径，比如 /var/www/upload/
        String rootPath = request.getSession().getServletContext().getRealPath(PATH_LINE) + PATH_LINE + "static" + PATH_LINE +"upload"+PATH_LINE;  
        // 根目录URL，可以指定绝对路径，比如 http://www.yoursite.com/upload/
        String rootUrl = request.getContextPath() + PATH_LINE + "static";  
        // 图片扩展名
        String[] fileTypes = new String[] {"gif", "jpg", "jpeg", "png", "bmp"};
  
        String dirName = request.getParameter("dir");
        if (dirName != null) {
            if (!Arrays.<String>asList(new String[] {"image", "flash", "media", "file"}).contains(
                    dirName)) {
                out.println("Invalid Directory name.");
                return;
            }
            rootPath += dirName + "/";
            rootUrl += dirName + "/";
            File saveDirFile = new File(rootPath);
            if (!saveDirFile.exists()) {
                saveDirFile.mkdirs();
            }
        }
        // 根据path参数，设置各路径和URL
        String path = request.getParameter("path") != null ? request.getParameter("path") : "";
        String currentPath = rootPath + path;
        String currentUrl = rootUrl + path;
        String currentDirPath = path;
        String moveupDirPath = "";
        if (!"".equals(path)) {
            String str = currentDirPath.substring(0, currentDirPath.length() - 1);
            moveupDirPath =
                    str.lastIndexOf("/") >= 0 ? str.substring(0, str.lastIndexOf("/") + 1) : "";
        }
  
        // 排序形式，name or size or type
        String order =
                request.getParameter("order") != null ? request.getParameter("order").toLowerCase()
                        : "name";
  
        // 不允许使用..移动到上一级目录
        if (path.indexOf("..") >= 0) {
            out.println("Access is not allowed.");
            return;
        }
        // 最后一个字符不是/
        if (!"".equals(path) && !path.endsWith("/")) {
            out.println("Parameter is not valid.");
            return;
        }
        // 目录不存在或不是目录
        File currentPathFile = new File(currentPath);
        if (!currentPathFile.isDirectory()) {
            out.println("Directory does not exist.");
            return;
        }
        // 遍历目录取的文件信息
        List<Hashtable> fileList = new ArrayList<Hashtable>();
        if (currentPathFile.listFiles() != null) {
            for (File file : currentPathFile.listFiles()) {
                Hashtable<String, Object> hash = new Hashtable<String, Object>();
                String fileName = file.getName();
                if (file.isDirectory()) {
                    hash.put("is_dir", true);
                    hash.put("has_file", (file.listFiles() != null));
                    hash.put("filesize", 0L);
                    hash.put("is_photo", false);
                    hash.put("filetype", "");
                } else if (file.isFile()) {
                    String fileExt =
                            fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
                    hash.put("is_dir", false);
                    hash.put("has_file", false);
                    hash.put("filesize", file.length());
                    hash.put("is_photo", Arrays.<String>asList(fileTypes).contains(fileExt));
                    hash.put("filetype", fileExt);
                }
                hash.put("filename", fileName);
                hash.put("datetime",
                        new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file.lastModified()));
                fileList.add(hash);
            }
        }
   
        if ("size".equals(order)) {
            Collections.sort(fileList, new SizeComparator());
        } else if ("type".equals(order)) {
             
            Collections.sort(fileList, new TypeComparator());
        } else {
            Collections.sort(fileList, new NameComparator());
         
        }
        Map<String, Object> msg = new HashMap<String, Object>();
        msg.put("moveup_dir_path", moveupDirPath);
        msg.put("current_dir_path", currentDirPath);
        msg.put("current_url", currentUrl);
        msg.put("total_count", fileList.size());
        msg.put("file_list", fileList);
        response.setContentType("application/json; charset=UTF-8");
        String msgStr = objectMapper.writeValueAsString(msg);
        out.println(msgStr);
    }
     
 
     
    @SuppressWarnings("rawtypes")
    class NameComparator implements Comparator {
        public int compare(Object a, Object b) {
            Hashtable hashA = (Hashtable) a;
            Hashtable hashB = (Hashtable) b;
            if (((Boolean) hashA.get("is_dir")) && !((Boolean) hashB.get("is_dir"))) {
                return -1;
            } else if (!((Boolean) hashA.get("is_dir")) && ((Boolean) hashB.get("is_dir"))) {
                return 1;
            } else {
                return ((String) hashA.get("filename")).compareTo((String) hashB.get("filename"));
            }
        }
    }
      
    @SuppressWarnings("rawtypes")
    class SizeComparator implements Comparator {
        public int compare(Object a, Object b) {
            Hashtable hashA = (Hashtable) a;
            Hashtable hashB = (Hashtable) b;
            if (((Boolean) hashA.get("is_dir")) && !((Boolean) hashB.get("is_dir"))) {
                return -1;
            } else if (!((Boolean) hashA.get("is_dir")) && ((Boolean) hashB.get("is_dir"))) {
                return 1;
            } else {
                if (((Long) hashA.get("filesize")) > ((Long) hashB.get("filesize"))) {
                    return 1;
                } else if (((Long) hashA.get("filesize")) < ((Long) hashB.get("filesize"))) {
                    return -1;
                } else {
                    return 0;
                }
            }
        }
    }
      
    @SuppressWarnings("rawtypes")
    class TypeComparator implements Comparator {
        public int compare(Object a, Object b) {
            Hashtable hashA = (Hashtable) a;
            Hashtable hashB = (Hashtable) b;
            if (((Boolean) hashA.get("is_dir")) && !((Boolean) hashB.get("is_dir"))) {
                return -1;
            } else if (!((Boolean) hashA.get("is_dir")) && ((Boolean) hashB.get("is_dir"))) {
                return 1;
            } else {
                return ((String) hashA.get("filetype")).compareTo((String) hashB.get("filetype"));
            }
        }
    }
}
